home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / pdisk.zip / PDISK.ASM < prev    next >
Assembly Source File  |  1989-01-12  |  11KB  |  439 lines

  1.     TITLE    DISK -- A Multiple Disk Driver
  2.     SUBTTL    Header and global definitions
  3.     PAGE    64D,132D    ; make line length 132
  4. ;    .286
  5.     .radix    16
  6.     OK186    EQU    (@Cpu and 02)
  7.  
  8. ;DISK_NO    EQU    1    ; should get this from makefile
  9. RQ        STRUC    ; Standard Request Header
  10. RQ_LEN        DB    ?     ; number of bytes passed  -- first field
  11. RQ_UCD        DB    ?     ; unit code
  12. RQ_CCD        DB    ?     ; command code
  13. RQ_STAT        DW    ?     ; status (return code)
  14. RQ_RES        DB    8 DUP(?) ; reserved area
  15. RQ        ENDS
  16. ; Status field bit equates
  17. STAT_ERR    EQU    8000    ; There was an error.  See low byte.
  18. STAT_BUSY    EQU    200    ; Busy.  Used in build BPB call.
  19. STAT_DONE    EQU    100    ; Operation complete.
  20. ; low byte error return codes.
  21. STAT_GEN_FAIL    EQU    0E    ; general failure
  22. STAT_READ_FAULT    EQU    0BH    ; read fault
  23. STAT_WRITE_FAULT EQU    0A    ; write fault
  24. STAT_NOT_FOUND    EQU    8    ; sector not found
  25. STAT_UNK_CMD    EQU    3    ; unknown command
  26. STAT_UNK_UNIT    EQU    1    ; unknown unit
  27. ;
  28. CSEG         SEGMENT
  29. ; start driver.  first section is data
  30. ; (though it is in the code segment)
  31.         ASSUME    CS:CSEG,DS:NOTHING,ES:NOTHING
  32. ;  special device header
  33. ; This MUST be at ORG 0 (i.e. the first code).
  34. START        EQU    $
  35. NEXT_DEV    DD    -1        ; ptr to next device
  36. ATTRIBUTE    DW    4800        ; block device, supports 3.x, ioctl
  37. STRATEGY    DW    DEV_STRAT    ; ptr to device strategy
  38. INTERRUPT    DW    DEV_INT        ; ptr to dev interrupt handler
  39. DEV_COUNT    DB    0        ; number of units
  40. DEV_NAME    DB    'SEGdsk','0'+DISK_NO    ; 7 bytes of filler
  41. DRVTBL  LABEL   WORD
  42.     DW    INIT
  43.     DW    MEDIA_CHK
  44. ; according to DOS tech manual, BUILD_BPB should never get called, as long as
  45. ; MEDIA_CHK always returns "media unchanged" [sic].  However, this is not true.
  46. ; DOS's "reserved" functions 1F and 32 call it, anyway.
  47.     DW    BUILD_BPB
  48.     DW    EXIT        ; would be IOCTL_IN
  49.     DW    DOTRANS
  50.     DW    CMDERR
  51.     DW    CMDERR
  52.     DW    CMDERR
  53.     DW    DOTRANS
  54.     DW    DOTRANS
  55.     DW    CMDERR
  56.     DW    CMDERR
  57.     DW    IOCTL_OUT
  58.     DW    EXIT
  59.     DW    EXIT
  60.     DW    REMOVE
  61.     DW    CMDERR
  62. PTRSAV    DD    ?    ; for DEVSTRAT
  63.     SUBTTL    Small Routines (interrupt, entry, exit, error, media check)
  64.     PAGE
  65. STRATP    PROC    FAR    ; device strategy
  66. DEV_STRAT:
  67.     MOV    WORD PTR CS:[PTRSAV],BX
  68.     MOV    WORD PTR CS:[PTRSAV+2],ES
  69.     RET
  70. STRATP    ENDP
  71.  
  72. DEV_INT:        ; device interrupt handler
  73. IF    OK186
  74.     PUSHA
  75. ELSE
  76.     PUSH    AX
  77.     PUSH    BX
  78.     PUSH    CX
  79.     PUSH    DX
  80.     PUSH    SI
  81.     PUSH    DI
  82.     PUSH    BP
  83. ENDIF
  84.     PUSH    DS
  85.     PUSH    ES
  86.     ASSUME  DS:CSEG
  87.     MOV    AX,CS        ; get normal data addressability (DS=CS)
  88.     MOV    DS,AX
  89.     LES    BP,[PTRSAV]
  90.     MOV    AL,ES:[BP].RQ_CCD        ; Command code
  91.     CMP    AL,10
  92.     JA    CMDERR            ; Bad command
  93.     CBW                ; = xor ah,ah
  94.     SHL    AX,1            ; 2 times command = word table index
  95.     MOV    SI,AX
  96.     JMP    WORD PTR [SI].DRVTBL        ; Index into table
  97. ;
  98. STD_BPB        STRUC        ; a bios parameter block
  99. B_PER_S        DW    ?
  100. SEC_PER_AU    DB    ?
  101. RES_SECTS    DW    ?
  102. NFATS        DB    ?
  103. NDIRENTS    DW    ?
  104. NSECTS        DW    ?
  105. MEDIA_DES    DB    ?
  106. NFATSECTS    DW    ?    ; last word of standard portion
  107. STD_BPB        ENDS
  108.  
  109. STD_BPB_LEN    EQU    TYPE STD_BPB
  110.  
  111. BPB        STRUC
  112.         DB    STD_BPB_LEN DUP (?)
  113. RELSEC        DD    ?    ; add-on: see part_rec.rel_sect
  114. PARTNO        DB    ?    ; save partition number of this drive
  115. BPB        ENDS
  116. ;
  117. BPB_NDX        DW    OFFSET BPB_SPACE
  118.         DW    (OFFSET BPB_SPACE)+(TYPE BPB)
  119.         DW    (OFFSET BPB_SPACE)+2*(TYPE BPB)
  120.         DW    (OFFSET BPB_SPACE)+3*(TYPE BPB)
  121. ;
  122. BBPBDATA    STRUC    ; build bpb data struct
  123. BP_RQ        DB    (TYPE RQ) DUP(?) ; standard part
  124. BP_MDES        DB    ?        ; media descriptor (input)
  125. BP_TRANS    DD    DWORD PTR ?    ; transfer address
  126. BP_RET1        DW    ?
  127. BP_RET2        DW    ?
  128. BBPBDATA    ENDS
  129. ;
  130. BUILD_BPB:
  131.     MOV    AL,ES:[BP].RQ_UCD
  132.     CBW
  133.     MOV    SI,AX
  134.     SHL    SI,1
  135.     MOV    SI,[SI].BPB_NDX
  136.     MOV    ES:[BP].BP_RET1,SI
  137.     MOV    ES:[BP].BP_RET2,CS
  138.     JMP    SHORT EXIT
  139. ;
  140. MCDATA        STRUC    ; media check data struct
  141. MC_RQ        DB    (TYPE RQ) DUP(?) ; standard part
  142. MC_MDES        DB    ?        ; media descriptor (input)
  143. MC_RET        DB    ?        ; returned byte: 1 if media unchanged
  144. MCDATA        ENDS
  145. ;
  146. MEDIA_CHK:    ; Winchesters never change
  147.     MOV    ES:[BP].MC_RET,1
  148.     JMP    SHORT EXIT
  149. REMOVE:
  150.     MOV    AX,STAT_DONE+STAT_BUSY    ; "busy" bit = non-removable medium
  151.     JMP    SHORT ERR1
  152. CMDERR:
  153.     MOV    AX,STAT_ERR+STAT_UNK_CMD+STAT_DONE    ; unknown command error
  154.     JMP    SHORT ERR1
  155.  
  156. IOCTL_OUT:            ; only valid return is a copy of the extended BPB
  157.     MOV    AL,ES:[BP].RQ_UCD
  158.     CBW                ; promote AL to AX with sign extension
  159.     SHL    AX,1            ; make device number into table offset
  160.     MOV    SI,AX
  161.     MOV    AX,ES
  162.     LES    DI,DWORD PTR ES:[BP].RW_TRANS
  163.     MOV    SI,[SI].BPB_NDX        ; now SI points to the correct BPB
  164.     MOV    CX,TYPE BPB        ; get length of data to transfer
  165.     REP    MOVSB
  166.     MOV    ES,AX
  167.     MOV    ES:[BP].RW_COUNT,TYPE BPB ; set length of data transferred
  168.     JMP    SHORT EXIT
  169.  
  170. EXITP   PROC    FAR        ; EXIT - All routines return through this path
  171. EXIT:   MOV    AX,STAT_DONE        ; "done" (no error)
  172. ERR1:   MOV    ES:[BP].RQ_STAT,AX    ; mark operation complete
  173.     POP    ES
  174.     POP    DS
  175. IF    OK186
  176.     POPA
  177. ELSE
  178.     POP    BP
  179.     POP    DI
  180.     POP    SI
  181.     POP    DX
  182.     POP    CX
  183.     POP    BX
  184.     POP    AX
  185. ENDIF
  186.     RET        ; restore regs and return
  187. EXITP   ENDP
  188.     SUBTTL    Read and Write sectors
  189.     PAGE
  190.  
  191. RWDATA        STRUC
  192. RW_RQ        DB    (TYPE RQ) DUP(?) ; standard part
  193. RW_MEDIA    DB    ?          ; media descriptor
  194. RW_TRANS    DD    DWORD PTR ?      ; transfer address
  195. RW_COUNT    DW    ?          ; # of sectors to transfer
  196. RW_START    DW    ?          ; first block to transfer
  197. RWDATA        ENDS
  198. ;
  199. ; local variables:
  200. DISK_ADDR    EQU    7F+DISK_NO    ; 0x80 = disk #1, 0x81 = disk 2.
  201. NSECS        DB    ?    ; number of sectors per track
  202. SHPROD        DW    ?    ; NHEADS*NSECS
  203. ;
  204. DOTRANS:
  205.     MOV    AL,ES:[BP].RQ_UCD
  206.     CBW                ; promote AL to AX with sign extension
  207.     MOV    SI,AX
  208.     INC    AX            ; (adjust for 1-based)
  209.     CMP    AL,[DEV_COUNT]
  210.     JLE    OK_COUNT
  211.     MOV    AX,STAT_ERR+STAT_DONE+STAT_UNK_UNIT
  212.     JMP    SHORT ERR1
  213. OK_COUNT:
  214.     SHL    SI,1            ; make device number into table offset
  215.     MOV    SI,[SI].BPB_NDX        ; now SI points to the correct BPB
  216.     MOV    BX,ES:[BP].RW_START    ; starting sector of request
  217.     MOV    DI,BX            ; start_sec+sec_trans>num_secs =>error
  218.     MOV    AX,ES:[BP].RW_COUNT
  219.     ADD    BX,AX
  220.     CMP    BX,[SI].NSECTS
  221.     JBE    OK_COUNT2
  222.     MOV    AX,STAT_ERR+STAT_DONE+STAT_NOT_FOUND
  223.     JMP    SHORT ERR1
  224. OK_COUNT2:
  225.     MOV    BX,AX            ; save
  226.     MOV    AX,WORD PTR [SI].RELSEC
  227.     MOV    DX,WORD PTR [SI+2].RELSEC
  228.     ADD    AX,DI        ; add starting relative sector word to request
  229.     ADC    DX,0        ; add carry, if any, to high word
  230.     DIV    [SHPROD] ; AX=DX:AX div CX (CX=nsects*nheads), DX=DX:AX mod CX
  231. IF    OK186
  232.     SHL    AH,6
  233. ELSE
  234.     MOV    CL,6    ; Need to put into screwy BIOS format
  235.     SHL    AH,CL
  236. ENDIF
  237.     XCHG    AL,AH
  238.     MOV    CX,AX
  239.     MOV    AX,DX    ; now get head and sector number
  240.     DIV    [NSECS]    ; now AH=sector number, AL=head number
  241.     MOV    DH,AL
  242.     OR    CL,AH
  243.     INC    CX    ; sector number is 1 based, not 0 based (from MOD)
  244.     MOV    DL,DISK_ADDR    ; drive code
  245.     MOV    AX,BX        ; get original RW_COUNT back
  246.     CMP    AX,80
  247.     JLE    BIOS_OK1
  248. BIOS_BAD1:
  249.     MOV    AX,STAT_ERR+STAT_DONE+STAT_GEN_FAIL
  250.     JMP    SHORT ERR1
  251. BIOS_OK1:
  252.     MOV    BX,WORD PTR ES:[BP].RW_TRANS
  253.     PUSH    CX
  254.     PUSH    DX
  255.     MOV    DI,AX
  256. IF    OK186
  257.     SHL    AX,9
  258. ELSE
  259.     MOV    CL,9
  260.     SHL    AX,CL
  261. ENDIF
  262.     MOV    DX,AX
  263.     ADD    AX,BX
  264.     JNC    BIOS_OK2
  265.     SUB    DX,AX
  266.     MOV    AX,DX
  267. IF    OK186
  268.     SHR    AX,9
  269. ELSE
  270.     SHR    AX,CL
  271. ENDIF
  272.     MOV    ES:[BP].RW_COUNT,AX
  273.     JMP    SHORT SKIP_OK2    ; skip restore of original AX
  274. BIOS_OK2:
  275.     MOV    AX,DI    ; original sector count was good
  276. SKIP_OK2:
  277.     ; following depends on fact that BIOS read fcn is 2, write is 3
  278.     MOV    AH,2    ; AL has number of sectors; AH gets op code
  279.     CMP    ES:[BP].RQ_CCD,4    ; 4=read
  280.     JE    DO_OP
  281.     INC    AH
  282. DO_OP:
  283.     POP    DX
  284.     POP    CX
  285.     PUSH    ES
  286.     MOV    ES,WORD PTR ES:[BP+2].RW_TRANS
  287.     INT    13
  288.     POP    ES
  289.     JNC    OK_TRANS    ; Carry bit unaffected by POP
  290.     CMP    AH,11        ; CRC error -- ignore
  291.     JNE    BIOS_BAD1
  292. OK_TRANS:
  293.     JMP    EXIT
  294. ;
  295. ; the BPB table should be the LAST thing declared before initialization code,
  296. ; as we throw away whatever we don't need of it.
  297. BPB_SPACE    BPB    4 DUP(<>) ; space for whatever BPB's we need
  298. ;
  299.     SUBTTL    Initialization code
  300.     PAGE
  301. ; Equates
  302. CR        EQU    0DH
  303. LF        EQU    0AH
  304. BOOT_BPB    EQU    0BH    ; offset of main BPB in boot sector
  305. BOOT_PARTTAB    EQU    1BE    ; offset of partition table in boot sector
  306. SIGNATURE    EQU    06
  307. ; Local Structs
  308. PART_REC    STRUC
  309. BOOT_IND    DB    ?
  310. S_HEAD        DB    ?
  311. S_SEC_CYL    DW    ?
  312. SYS_IND        DB    ?
  313. E_HEAD        DB    ?
  314. E_SEC_CYL    DW    ?
  315. REL_SECT    DD    ?
  316. NUM_SECT    DD    ?
  317. PART_REC    ENDS
  318. ;
  319. INITDATA    STRUC
  320. INI_RQ        DB    (TYPE RQ) DUP(?) ; standard part
  321. INI_NUNITS    DB    ?          ; number of units in driver
  322. INI_END_OFF    DW    ?          ; ending address offset
  323. INI_END_SEG    DW    ?          ; ending address segment
  324. INI_BPB_OFF    DW    ?          ; BPB array offset
  325. INI_BPB_SEG    DW    ?          ; BPB array segment
  326. INI_BLOCKDEV    DB    ?
  327. INITDATA    ENDS
  328. ; Data
  329.